/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/7/1 20:44
  *
  * @file       hd_ina226.c
  * @brief      Xxx hardware driver.
  *
  * @note       This file contains the hardware driver for the Xxx.
  *
  * @warning    None.
  ******************************************************************************
  * Change Logs:
  *   Date          Author       Notes
  *   2024/7/1     Chris        the first version
  *
  ******************************************************************************
  */

#include "hd_ina226.h"


static void INA226_init(INA226 *this) {
    uint16_t tmp = 0x2741;
    this->write_data16(this, INA226_CONFIG, &tmp);
    tmp = 0x000A;
    this->write_data16(this, INA226_CALIBRATION, &tmp);
}

static uint8_t INA226_readShuntVoltage(INA226 *this, uint16_t *shuntVoltage) {
    return this->read_data16(this, INA226_SHUNT_VOLTAGE, shuntVoltage);
}

static uint8_t INA226_readBusVoltage(INA226 *this, uint16_t *busVoltage) {
    return this->read_data16(this, INA226_BUS_VOLTAGE, busVoltage);
}

static uint8_t INA226_readPower(INA226 *this, uint16_t *power) {
    return this->read_data16(this, INA226_POWER, power);
}

static uint8_t INA226_readCurrent(INA226 *this, uint16_t *current) {
    return this->read_data16(this, INA226_CURRENT, current);
}

static uint8_t INA226_readManuID(INA226 *this, uint16_t *id) {
    return this->read_data16(this, INA226_MANU_ID, id);
}

static uint8_t INA226_readDieID(INA226 *this, uint16_t *id) {
    return this->read_data16(this, INA226_DIE_ID, id);
}

static uint8_t INA226_readData16(INA226 *this, uint8_t regAddr, uint16_t *regVal) {
    return this->i2c->read(this->i2c, INA226_SLAVE_ADDR, regAddr, (uint8_t *) regVal, 2);
}

static uint8_t INA226_writeData16(INA226 *this, uint8_t regAddr, uint16_t *regVal) {
    return this->i2c->send(this->i2c, INA226_SLAVE_ADDR, regAddr, (uint8_t *) regVal, 2);
}

static INA226 *build(I2C *i2c) {
    INA226 *ina226 = malloc(sizeof(INA226));

    Driver_add(ina226, GEN_PERM);

    ina226->i2c          = i2c;
    ina226->init         = &INA226_init;
    ina226->read_shunt   = &INA226_readShuntVoltage;
    ina226->read_bus     = &INA226_readBusVoltage;
    ina226->read_power   = &INA226_readPower;
    ina226->read_current = &INA226_readCurrent;
    ina226->read_manu_id = &INA226_readManuID;
    ina226->read_die_id  = &INA226_readDieID;
    ina226->write_data16 = &INA226_writeData16;
    ina226->read_data16  = &INA226_readData16;

    return ina226;
}

const struct INA226Class INA226Builder = {.build = &build};

